package com.yycx.module.bus.provider.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.yycx.common.base.entity.EntityMap;
import com.yycx.common.base.utils.FlymeUtils;
import com.yycx.common.mybatis.base.service.impl.BaseServiceImpl;
import com.yycx.common.mybatis.model.ResultBody;
import com.yycx.common.mybatis.query.CriteriaQuery;
import com.yycx.common.mybatis.query.CriteriaSave;
import com.yycx.common.security.OpenHelper;
import com.yycx.common.utils.DateUtils;
import com.yycx.common.utils.OrderNoUtil;
import com.yycx.common.utils.SequenceUtils;
import com.yycx.module.admin.client.entity.BaseUser;
import com.yycx.module.bus.client.entity.BusDept;
import com.yycx.module.bus.client.entity.BusExpense;
import com.yycx.module.bus.client.entity.BusSaleman;
import com.yycx.module.bus.provider.mapper.BusExpenseMapper;
import com.yycx.module.bus.provider.service.BusDeptService;
import com.yycx.module.bus.provider.service.BusExpenseService;
import com.yycx.module.bus.provider.service.BusPaymenttypeService;
import com.yycx.module.bus.provider.service.BusSalemanService;
import com.yycx.module.system.client.entity.SysBank;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 费用报销接口实现类
 *
 * @author flyme
 * @date 2023-07-29
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class BusExpenseServiceImpl extends BaseServiceImpl<BusExpenseMapper, BusExpense> implements BusExpenseService {


    @Autowired
    private BusDeptService deptService;
    @Autowired
    private BusSalemanService busSalemanService;
    @Autowired
    private OrderNoUtil orderNoUtil;
    @Autowired
    private BusPaymenttypeService busPaymenttypeService;

    @Override
    public ResultBody beforeAdd(CriteriaSave cs, BusExpense expense, EntityMap extra) {
        BusDept busDept = deptService.getById(expense.getDeptId());
        Long companyId = busDept.getCompanyId();
        expense.setCompanyId(companyId);
        expense.setExpenseNo(getOrderNo(companyId));
        expense.setUserId(OpenHelper.getUserId());
        return ResultBody.ok();
    }

    private String getOrderNo(Long companyId) {
        CriteriaQuery<BusExpense> cq = new CriteriaQuery(BusExpense.class);
        cq.select("expenseNo");
        cq.eq(true, "companyId", companyId);
        cq.limit(1);
        cq.orderByDesc("createTime");
        String depositNo = getObj(cq, e -> e.toString());
        String date = DateUtils.formatDate(DateUtils.getNowDate(), "yyyyMMdd");
        String firstNo = date + "001";
        if (FlymeUtils.isNotEmpty(depositNo)) {
            if (depositNo.length() != 11) {
                return orderNoUtil.getIncrementNum();
            }
            String lastNo = depositNo.substring(8);
            Long no = Long.parseLong(lastNo) + 1;
            return date + SequenceUtils.getSequence(no);
        }
        return firstNo;
    }


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<BusExpense> cq, BusExpense expense, EntityMap requestMap) {

        String beginDate = requestMap.get("beginDate");
        String endDate = requestMap.get("endDate");
        cq.select(BusExpense.class, "*");
        cq.select(BusDept.class, "deptName");
        cq.addSelect(BaseUser.class, "nickName");
        cq.createJoin(BusDept.class).setMainField("deptId").setJoinField("deptId");
        cq.eq(BusExpense.class, "companyId", OpenHelper.getCompanyId());
        cq.createJoin(BaseUser.class).setMainField("userId");


        cq.addSelect(BusSaleman.class, "saleManName");
        cq.createJoin(BusSaleman.class);
        cq.addSelect(SysBank.class, "bankName");
        cq.createJoin(SysBank.class);

        cq.like(StrUtil.isNotEmpty(cq.getParams("expenseNo")), "expenseNo", cq.getParams("expenseNo"));
        cq.eq(BusExpense.class, "expenseType");
        cq.like(BusExpense.class, "expense");
        cq.eq(BusExpense.class, "deptId");
        if (FlymeUtils.isNotEmpty(beginDate)) {
            cq.ge(BusExpense.class, "payDate", beginDate);
        }
        if (FlymeUtils.isNotEmpty(endDate)) {
            cq.le(BusExpense.class, "payDate", endDate);
        }
        cq.eq(BusExpense.class, "companyId", OpenHelper.getCompanyId());
        cq.orderByDesc("expense.createTime");
        return ResultBody.ok();
    }

    @Override
    public ResultBody uploadFile(MultipartFile file) {

        try {
            InputStream inputStream = file.getInputStream();
            ExcelReader excelReader = ExcelUtil.getReader(inputStream);
            List<List<Object>> read = excelReader.read(1, excelReader.getRowCount());

            List<BusExpense> list = new ArrayList<>();
            Long companyId = OpenHelper.getCompanyId();
            String lastNo = getOrderNo(companyId).substring(8);
            String yyyyMMdd = DateUtils.formatDate(DateUtils.getNowDate(), "yyyyMMdd");

            Map<String, String> collect = busPaymenttypeService.list().stream().collect(Collectors.toMap(c -> c.getPaymentTypeName(), c -> c.getPaymentTypeCode()));

            for (int i = 0; i < read.size(); i++) {
                List<Object> objects = read.get(i);
                BusExpense expense = new BusExpense();
                expense.setCompanyId(companyId);
                Long no = Long.parseLong(lastNo) + (i + 1);
                expense.setExpenseNo(yyyyMMdd + SequenceUtils.getSequence(no));
                expense.setUserId(OpenHelper.getUserId());
                BusDept busDept = deptService.getByDeptName(objects.get(0).toString(), OpenHelper.getCompanyId());
                expense.setDeptId(busDept != null ? busDept.getDeptId() : null);
                if (busDept != null) {
                    BusSaleman saleman = busSalemanService.getBySaleManName(busDept.getDeptId(), objects.get(1).toString());
                    expense.setSaleManId(saleman != null ? saleman.getSaleManId() : null);
                }
                expense.setExpense(objects.get(2).toString());
                expense.setExpenseType(collect.get(objects.get(3).toString()));
                expense.setExpenseAmount(new BigDecimal(objects.get(4).toString()));
                expense.setPayDate(objects.get(5).toString().substring(0, 10));
                list.add(expense);
            }

            if (CollUtil.isEmpty(list)) {
                return ResultBody.failed("未查询到数据");
            }

            return ResultBody.ok(this.saveBatch(list));

        } catch (Exception e) {
            return ResultBody.failed(e.getMessage());

        }
    }


}
